package com.xframe.common.core.service.login;

import cn.hutool.core.util.IdUtil;
import com.xframe.domain.role.IUserCredentials;
import com.xframe.common.core.exception.BusinessException;
import com.xframe.xdal.core.util.StringUtil;
import com.xframe.xdal.core.util.redis.RedisAccess;

import static com.xframe.common.core.constant.ErrorConstant.*;
import static com.xframe.common.core.dto.ErrorCode.*;
/**
 * 功能描述: 登录令牌采用UUID，持久化设备采用REDIS
 *
 * @author xufeng
 * @version 1.0
 * @date 2023-5-31
 */
public class UserTokenService implements ITokenService {


    /**
     * 创建一个令牌
     * @param userCredentials 用户凭证
     *
     * @return token令牌
     */
    @Override
    public String createToken(IUserCredentials userCredentials) {

        return IdUtil.fastSimpleUUID();
    }
    /**
     * 根据令牌和数据类型获得一个用户凭证
     * @param token 令牌
     * @param dataType 数据类型
     * @param isNullthrow 如果为空是否抛出异常
     *
     * @return userCredentials 用户凭证
     */
    @Override
    public IUserCredentials getUserCredentials(String token,Class<?> dataType, boolean isNullthrow) {
        try {
            Object userObj = RedisAccess.getGetCmd().getObject(token, dataType);
            if (userObj == null && isNullthrow) {
                throw new BusinessException(TOKEN_MISS, TOKEN_MISS_MSG);
            } else {

                return (IUserCredentials) userObj;
            }
        }catch (Exception exception){
            if(isNullthrow){
                throw new BusinessException(TOKEN_MISS, TOKEN_MISS_MSG);
            }else {
                return null;
            }
        }
    }
    /**
     * 保存令牌到持久化设置上
     * @param token 令牌
     * @param userCredentials 用户凭证
     * @param second 令牌过期时间
     *
     * @return
     */
    @Override
    public void saveUserCredentials(String token,IUserCredentials userCredentials,int second) {
        //写入缓存
        if(userCredentials == null) {
            throw new BusinessException(ARGS_NULL,ARGS_NULL_MSG);
        }
        RedisAccess.getSetCmd().setObject(token, userCredentials, second);
        RedisAccess.getSetCmd().set(userCredentials.getUserId().toString(), token, second);
    }


    /**
     * 更新令牌的TTL
     * @param token 令牌
     * @param userCredentials 用户凭证
     * @param second 令牌过期时间
     *
     * @return
     */
    @Override
    public void updateUserCredentials(String token, IUserCredentials userCredentials, int second) {
        if(userCredentials != null && StringUtil.isNotEmpty(token) && second > 0){
            RedisAccess.getKeyCmd().expire(token, second);
            RedisAccess.getKeyCmd().expire(userCredentials.getUserId().toString(), second);
        }
    }

    /**
     * 根据一个用户凭证ID来判断登录状态
     * @param userId 用户凭证ID
     *
     * @return true已经登录 false没有登陆
     */
    @Override
    public boolean existsUserCredentials(String userId) {
        return RedisAccess.getGetCmd().get(userId) != null;
    }


    /**
     * 删除一个用户凭证
     * @param userCredentials 用户凭证
     *
     * @return
     */
    @Override
    public void delUserCredentials(IUserCredentials userCredentials){
        if(userCredentials != null) {
            RedisAccess.getKeyCmd().del(userCredentials.getToken(), userCredentials.getUserId().toString());
        }
    }
}
